import { computed, nextTick, reactive, toRaw, watch } from 'vue'
import type { CSSObject, StorageStore } from '@shared/types'
import isEqual from 'deep-equal'
import { typeString } from '.'

let isInitialized = false
const pool = new Set<() => void>()

export function onInitialized(callback: () => void) {
  isInitialized ? nextTick(callback) : pool.add(callback)
}

const defaultStore: StorageStore = {
  docsApis: [],
  cssInjectList: [],
  cssInjectActive: ''
}

export const storageStore = reactive<StorageStore>(structuredClone(defaultStore))

export const cssObject = computed<CSSObject>(() => {
  return (
    storageStore.cssInjectList.find(({ value }) => storageStore.cssInjectActive === value) ?? {
      value: '',
      css: ''
    }
  )
})

chrome?.storage?.local
  .get(structuredClone(defaultStore))
  .then((data) => {
    Object.assign(storageStore, data)
  })
  .finally(() => {
    // 创建监听，及时保存
    for (const key in defaultStore) {
      watch(
        () => storageStore[key as keyof StorageStore],
        (value) => {
          chrome.storage.local.set({ [key]: toRaw(value) })
        },
        { deep: true }
      )
    }

    // 初始化
    isInitialized = true
    nextTick(() => {
      pool.forEach((callback) => {
        pool.delete(callback)
        callback()
      })
    })
  })

chrome?.storage?.onChanged.addListener((changes) => {
  const keys = Object.keys(changes) as (keyof StorageStore)[]
  keys.forEach((key) => {
    if (key in defaultStore) {
      const storeValue = storageStore[key]
      const value = changes[key].newValue ?? structuredClone(defaultStore[key])
      if (typeString(storeValue) === typeString(value) && !isEqual(storageStore[key], value)) {
        storageStore[key] = value
      }
    }
  })
})
